/* Copyright 2012 Nathan Begle
    This file is part of pcoursemanager.

    pcoursemanager is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    pcoursemanager is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with pcoursemanager.  If not, see <http://www.gnu.org/licenses/>.
 */

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

public class Manager implements ActionListener, WindowListener {
	System_Tray tray = null;
	Add_Window addWindow = null;
	Period_Window periodWindow = null;
	List<Course> connections = null;
	long update_period;
	Thread connectionThread;
	
	public Manager()
	{
		tray = new System_Tray(this);
		
		connections = new ArrayList<Course>();
		update_period = 900000;
		
		load_save_data();
		
		if(connections.size() <= 0) {
			open_add_window();
		}
		
		connectionThread = new Thread(connectionRun);
		connectionThread.run();
	}
	
	public void addCourse(int year, int semester, long crn)
	{
		synchronized(connections) {
			synchronized(tray) {
				try {
					connections.add(new Course(year, semester, crn, this));

					if(addWindow != null) addWindow.resetWindow();
					
					for(Course i : connections)
					{
						if(i.getCourseString().equals(i.setCourseString(year, semester, crn)))
						{
							i.update();
							tray.addCourse(i.getMenuItem());
							break;
						}
					}
				} catch (Exception e) {
					for(Course i : connections)
					{
						if(i.getCourseString().equals(i.setCourseString(year, semester, crn)))
						{
							connections.remove(i);
							break;
						}
					}
					if(addWindow != null) {
						addWindow.errCRN();
						addWindow.errSemester();
						addWindow.errYear();
					}
				}
				
				(new Save_Data()).save_to_file(connections);
			}
		}
	}
	
	public void removeCourse(String course)
	{
		synchronized(connections) {
			synchronized(tray) {
				for(Course i : connections)
				{
					if(i.getCourseString().equals(course))
					{
						i.remove_window();
						tray.removeCourse(i.getMenuItem());
						connections.remove(i);
						break;
					}
				}
				synchronized(connections) {
					(new Save_Data()).save_to_file(connections);
				}
			}
		}
	}
	
	void remove_add_window()
	{
		addWindow = null;
	}
	
	void updateConnections()
	{
		synchronized(connections) {
			synchronized(tray) {
				String message = "";
				for(Course i : connections)
				{
					try {
						i.update();
						if(i.connection.available)
						{
							message = message + i.course + "\n";
						}
					} catch (Exception e) {}
				}
				if(!message.equals(""))
				{
					tray.displayMessage("Courses are available", message);
					tray.setAvailImage();
				}
				else
				{
					tray.setNotAvailImage();
				}
			}
		}
	}
	
	boolean exists(int year, int semester, long crn)
	{
		synchronized(connections) {
			for(Course i : connections)
			{
				if(i.course_year == year && i.course_semester == semester && i.course_crn == crn)
				{
					return true;
				}
			}
			return false;
		}
	}
	
	private void open_add_window()
	{
		if(addWindow == null)
		{
			addWindow = new Add_Window(this, "add_course_bt", this);
		}
		else
		{
			addWindow.bring_to_front();
		}
	}
	
	boolean load_save_data()
	{
		FileReader fileReader;
		File file = new File("save_data", "pcm_save_file.txt");
		BufferedReader reader;
		String[] parsedLine = null;
		String tempLine;
		
		try {
			fileReader = new FileReader(file);
			reader = new BufferedReader(fileReader);
			
			while((tempLine=reader.readLine()) != null)
			{
				//System.out.println(tempLine);
				parsedLine = tempLine.split("&");
				addCourse(Integer.parseInt(parsedLine[1]), Integer.parseInt(parsedLine[0]), Long.parseLong(parsedLine[2]));
			}
			reader.close();
			fileReader.close();
		} catch (Exception e) {
			//System.out.println("Didn't load");
			return true;
		}
		return false;
	}
	
	Runnable connectionRun = new Runnable() {
		public void run() {
			while(true)
			{
				//System.out.print("testing\n");

				updateConnections();

				try {
					Thread.sleep(update_period);
				} catch (InterruptedException e) {}
			}
		}
	};

	public void actionPerformed(ActionEvent e) {	
		//System.out.println(e.getActionCommand());
		if("Exit".equals(e.getActionCommand()))
		{
			System.exit(0);
		}
		else if("Add Course".equals(e.getActionCommand()))
		{
			open_add_window();
		}
		else if("add_course_bt".equals(e.getActionCommand()))
		{
			int tempYear = addWindow.getYear();
			long tempCRN = addWindow.getCRN();
			int tempSem = addWindow.getSemester();
			if(tempCRN != -1 && tempYear != -1 && !exists(tempYear, tempSem, tempCRN))
			{
				addCourse(tempYear, tempSem, tempCRN);
			}
		} else if("Set Update Period".equals(e.getActionCommand())) {
			if(periodWindow == null)
			{
				periodWindow = new Period_Window(this, this, update_period);
			} else {
				periodWindow.bringFront();
			}
		} else if("per_bt".equals(e.getActionCommand()))
		{
			long tempPer = periodWindow.getPeriod();
			if(tempPer != -1)
			{
				update_period = tempPer;
				periodWindow.disposeWindow();
				periodWindow = null;
			}
		}
		else
		{
			synchronized(connections) {
				for(Course i : connections)
				{
					if(i.course.equals(e.getActionCommand()))
					{
						i.open_window(this);
						break;
					}
					else if(e.getActionCommand().equals(i.course+"_bt"))
					{
						removeCourse(i.course);
						break;
					}
				}
			}
		}
	}
	
	public void windowClosing(WindowEvent e) {
		if(addWindow != null && addWindow.hasFocus())
		{
			addWindow.disposeWindow();
			addWindow = null;
		} else if(periodWindow != null && periodWindow.hasFocus())
		{
			periodWindow.disposeWindow();
			periodWindow = null;
		}
	}
	
	public void windowClosed(WindowEvent e) {}
	public void windowActivated(WindowEvent e) {}
	public void windowDeactivated(WindowEvent e) {}
	public void windowDeiconified(WindowEvent e) {}
	public void windowIconified(WindowEvent e) {}
	public void windowOpened(WindowEvent e) {}
}

